package models

import (
    "SnowId/config"
    "SnowId/tools"
    "bytes"
    "database/sql"
    "fmt"
    _ "github.com/go-sql-driver/mysql"
    "time"
)
var db *sql.DB
type BaseModel struct {
    TableName string
}
func init() {
    dbConfig := config.GetDbConfig()
    dbLink := fmt.Sprintf("%s:%s@tcp(%s:%d)/%s?charset=utf8mb4", dbConfig.DbUser, dbConfig.DbPass, dbConfig.DbHost,
        dbConfig.DbPort,
        dbConfig.DbName) + "&loc=Asia%2FChongqing"
    var errDb error
    db, errDb = sql.Open(dbConfig.DbDriver, dbLink)
    
    if errDb != nil {
        panic(errDb)
    }
    db.SetMaxOpenConns(dbConfig.DbMaxOpenConn)
    db.SetMaxIdleConns(dbConfig.DbMaxIdleConn)
    //defer db.Close()
    errPing := db.Ping()
    if errPing != nil {
        panic(errPing.Error()+ "aaaaa~~~~")
    }
}

func (base *BaseModel) SetTableName(tblName string) {
    base.TableName = tblName
}

func (base *BaseModel) QueryOne(fields string, whereCondition string) interface{} {
    sqlStr := fmt.Sprintf("SELECT %s FROM %s WHERE 1 %s LIMIT 1", fields, base.TableName, whereCondition)
    
    rows, err := db.Query(sqlStr)
    defer rows.Close()
    if err != nil {
        panic(err)
    }
    return rows
}

func (base *BaseModel) QueryRows(fields string, whereCondition string, limit int) interface{} {
    sqlStr := fmt.Sprintf("SELECT %s FROM %s WHERE 1 %s LIMIT %d", fields, base.TableName, whereCondition, limit)
    
    rows, err := db.Query(sqlStr)
    defer rows.Close()
    if err != nil {
        panic(err)
    }
    return rows
}

func (base *BaseModel) InsertOne(data map[string]interface{}) int64 {
    var fieldsBuf bytes.Buffer
    var valuesQmBuf bytes.Buffer
    data["micro_time"] = time.Now().UnixNano()/1e3
    var values = make([]interface{}, 0, len(data))
    for k, v := range data {
        fieldsBuf.WriteString(k)
        fieldsBuf.WriteString(",")
        valuesQmBuf.WriteString("?,")
        values = append(values, v)
    }
    
    fields := fieldsBuf.String()
    fields = tools.SubStr(fields, 0, -1)
    valuesQm := valuesQmBuf.String()
    valuesQm = tools.SubStr(valuesQm, 0, -1)
    sqlStr := fmt.Sprintf("INSERT INTO %s (%s) VALUES (%s) ", base.TableName, fields, valuesQm)
    
    //stmt, errPrep := db.Prepare(`INSERT INTO ids (id) VALUES (?)`)
    stmt, errPrep := db.Prepare(sqlStr)
    defer stmt.Close()
    if errPrep != nil {
       panic(errPrep.Error() + "====1")
    }
    var affects int64 = 0
    result, errExec := stmt.Exec(values...)
    if errExec != nil {
       panic(errExec.Error() + "====2")
    }
    affects, errAff := result.RowsAffected()
    if errAff != nil {
       panic(errAff.Error() + "====3")
    }
    return affects
}